/**
 * Copyright 2008 Adam Ruggles.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package kiff.entity;

import java.util.Date;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Version;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

/**
 * Post Entity.
 * @author Adam
 * @version $Id: Post.java 72 2008-11-26 21:14:10Z a.ruggles $
 */
@Entity @Table(name = "posts")
public class Post implements CoreEntity<Integer>, TrackAware, UpdateAware<Post>, Comparable<Post> {
    /**
	 * Serial Version UID.
	 */
	private static final long serialVersionUID = -5201747710412835561L;

	/**
     * A boolean flag on whether this post has been approved.
     */
    private Boolean approved;

    /**
     * Is bbcode parsing enabled.
     */
    private Boolean bbCodeEnabled;

    /**
     * The Body/Text of the post.
     */
    private String body;

    /**
     * The date and time the post was created.
     */
    private Date created;

    /**
     * The User that created this post.
     */
    private User creator;

    /**
     * IP of the user that created the post.
     */
    private String creatorIpAddress;

    /**
     * Is emoticon parsing enabled.
     */
    private Boolean emotesEnabled;

    /**
     * The forum that this post and topic belong to.
     */
    private Forum forum;

    /**
     * Is html parsing enabled.
     */
    private Boolean htmlEnabled;

    /**
     * The unique identifier of the Post object.
     */
    private Integer id;

    /**
     * The date and time the post was last modified.
     */
    private Date modified;

    /**
     * A boolean flag on whether this post has been marked as reported.
     */
    private Boolean reported;

    /**
     * Is user signatures enabled.
     */
    private Boolean signatureEnabled;

    /**
     * The Title/Subject of the post.
     */
    private String subject;

    /**
     * The Topic that the post is associated with.
     */
    private Topic topic;

    /**
     * The version of the Post object, for optimistic concurrency control.
     */
    private Integer version;

    /**
	 * @see java.lang.Comparable#compareTo(java.lang.Object)
	 */
	public int compareTo(final Post post) {
		if (this.created == null || post == null || post.getCreated() == null) {
			return -1;
		}
		return this.created.compareTo(post.getCreated());
	}

	/**
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (!(obj instanceof Post)) {
			return false;
		}
		Post rhs = (Post) obj;
		return new EqualsBuilder()
			.append(subject, rhs.getSubject())
			.append(created, rhs.getCreated())
			.isEquals();
	}

	/**
	 * Returns approved.
	 * @return Returns the approved.
	 */
	@Basic(optional = false)
	public Boolean getApproved() {
		return approved;
	}
    /**
	 * Returns bbCodeEnabled.
	 * @return Returns the bbCodeEnabled.
	 */
	@Basic(optional = false)
	public Boolean getBbCodeEnabled() {
		return bbCodeEnabled;
	}
    /**
     * Returns body.
     * @return Returns the body.
     */
    @Lob @Basic(optional = false)
    public String getBody() {
        return body;
    }
    /**
     * Returns created.
     * @return Returns the created.
     */
    @Basic(optional = false) @Temporal(TemporalType.TIMESTAMP)
    public Date getCreated() {
        return created;
    }
    /**
     * Returns creator.
     * @return Returns the creator.
     */
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "creator_id")
    public User getCreator() {
        return creator;
    }
    /**
     * Returns creatorIpAddress.
     * @return Returns the creatorIpAddress.
     */
    @Column(length = 40, nullable = false)
    public String getCreatorIpAddress() {
        return creatorIpAddress;
    }
    /**
	 * Returns emotesEnabled.
	 * @return Returns the emotesEnabled.
	 */
	@Basic(optional = false)
	public Boolean getEmotesEnabled() {
		return emotesEnabled;
	}
    /**
	 * Returns forum.
	 * @return Returns the forum.
	 */
	@ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "forum_id")
	public Forum getForum() {
		return forum;
	}
    /**
	 * Returns htmlEnabled.
	 * @return Returns the htmlEnabled.
	 */
	@Basic(optional = false)
	public Boolean getHtmlEnabled() {
		return htmlEnabled;
	}
    /**
     * Returns id.
     * @return Returns the id.
     */
    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    public Integer getId() {
        return id;
    }
    /**
     * Returns modified.
     * @return Returns the modified.
     */
    @Basic(optional = false) @Temporal(TemporalType.TIMESTAMP)
    public Date getModified() {
        return modified;
    }

	/**
	 * Returns reported.
	 * @return Returns the reported.
	 */
	@Basic(optional = false)
	public Boolean getReported() {
		return reported;
	}

	/**
	 * Returns signatureEnabled.
	 * @return Returns the signatureEnabled.
	 */
	@Basic(optional = false)
	public Boolean getSignatureEnabled() {
		return signatureEnabled;
	}

	/**
     * Returns subject.
     * @return Returns the subject.
     */
    @Column(length = 200, nullable = false)
    public String getSubject() {
        return subject;
    }

    /**
     * Returns topic.
     * @return Returns the topic.
     */
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "topic_id")
    public Topic getTopic() {
        return topic;
    }

    /**
     * Returns version.
	 * @return Returns the version.
	 */
    @Version
	public Integer getVersion() {
		return version;
	}

    /**
	 * @see java.lang.Object#hashCode()
	 */
	public int hashCode() {
		return new HashCodeBuilder(31, 37)
			.append(subject)
			.append(created)
			.toHashCode();
	}

	/**
     * Sets approved.
     * @param approved The approved to set.
     */
    public void setApproved(final Boolean approved) {
        this.approved = approved;
    }
    /**
     * Sets bbCodeEnabled.
     * @param bbCodeEnabled The bbCodeEnabled to set.
     */
    public void setBbCodeEnabled(final Boolean bbCodeEnabled) {
        this.bbCodeEnabled = bbCodeEnabled;
    }
    /**
     * Sets body.
     * @param body The body to set.
     */
    public void setBody(final String body) {
        this.body = body;
    }
	/**
     * Sets created.
     * @param created The created to set.
     */
    public void setCreated(final Date created) {
        this.created = created;
    }
	/**
     * Sets creator.
     * @param creator The creator to set.
     */
    public void setCreator(final User creator) {
        this.creator = creator;
    }
	/**
     * Sets creatorIpAddress.
     * @param creatorIpAddress The creatorIpAddress to set.
     */
    public void setCreatorIpAddress(final String creatorIpAddress) {
        this.creatorIpAddress = creatorIpAddress;
    }
	/**
     * Sets emotesEnabled.
     * @param emotesEnabled The emotesEnabled to set.
     */
    public void setEmotesEnabled(final Boolean emotesEnabled) {
        this.emotesEnabled = emotesEnabled;
    }
	/**
	 * Sets forum.
	 * @param forum The forum to set.
	 */
	public void setForum(final Forum forum) {
		this.forum = forum;
	}
	/**
     * Sets htmlEnabled.
     * @param htmlEnabled The htmlEnabled to set.
     */
    public void setHtmlEnabled(final Boolean htmlEnabled) {
        this.htmlEnabled = htmlEnabled;
    }
	/**
     * Sets id.
     * @param id The id to set.
     */
    public void setId(final Integer id) {
        this.id = id;
    }
	/**
     * Sets modified.
     * @param modified The modified to set.
     */
    public void setModified(final Date modified) {
        this.modified = modified;
    }
	/**
     * Sets reported.
     * @param reported The reported to set.
     */
    public void setReported(final Boolean reported) {
        this.reported = reported;
    }
	/**
     * Sets signatureEnabled.
     * @param signatureEnabled The signatureEnabled to set.
     */
    public void setSignatureEnabled(final Boolean signatureEnabled) {
        this.signatureEnabled = signatureEnabled;
    }
	/**
     * Sets subject.
     * @param subject The subject to set.
     */
    public void setSubject(final String subject) {
        this.subject = subject;
    }
	/**
     * Sets topic.
     * @param topic The topic to set.
     */
    public void setTopic(final Topic topic) {
        this.topic = topic;
    }
	/**
	 * Sets version.
	 * @param version The version to set.
	 */
	public void setVersion(final Integer version) {
		this.version = version;
	}
	/**
	 * @see java.lang.Object#toString()
     */
	public String toString() {
		return new ToStringBuilder(this)
			.append("id", id)
			.append("subject", subject)
			.append("created", created)
			.append("modified", modified)
			.append("approved", approved)
			.append("IP", creatorIpAddress)
			.append("html", htmlEnabled)
			.append("bbcode", bbCodeEnabled)
			.append("emotes", emotesEnabled)
			.append("signature", signatureEnabled)
			.append("reported", reported)
			.toString();
	}

	/**
	 * @see kiff.entity.UpdateAware#update(java.lang.Object)
	 */
	public void update(final Post entity) {
		if (entity.getApproved() != null) {
			this.approved = entity.getApproved();
		}
		if (entity.getBbCodeEnabled() != null) {
			this.bbCodeEnabled = entity.getBbCodeEnabled();
		}
		if (entity.getBody() != null) {
			this.body = entity.getBody();
		}
		if (entity.getForum() != null) {
			this.forum = entity.getForum();
		}
		if (entity.getHtmlEnabled() != null) {
			this.htmlEnabled = entity.getHtmlEnabled();
		}
		if (entity.getReported() != null) {
			this.reported = entity.getReported();
		}
		if (entity.getSignatureEnabled() != null) {
			this.signatureEnabled = entity.getSignatureEnabled();
		}
		if (entity.getEmotesEnabled() != null) {
			this .emotesEnabled = entity.getEmotesEnabled();
		}
		if (entity.getSubject() != null) {
			this.subject = entity.getSubject();
		}
		if (entity.getTopic() != null) {
			this.topic = entity.getTopic();
		}
	}
}
